package tp.pr5.instructions;

import tp.pr5.Constants;
import tp.pr5.NavigationModule;
import tp.pr5.RobotEngine;
import tp.pr5.Rotation;
import tp.pr5.instructions.exceptions.InstructionExecutionException;
import tp.pr5.instructions.exceptions.WrongInstructionFormatException;
import tp.pr5.items.ItemContainer;

/**
 * Its execution rotates the robot This Instruction works if the robot writes TURN LEFT or RIGHT or GIRAR LEFT or RIGHT
 *
 */
public class TurnInstruction implements Instruction{
	private NavigationModule navigation;
	private RobotEngine engine; 
	private Rotation rotation;
	
	/**
	 * It builds a default TurnInstruction
	 */
	public TurnInstruction()
	{}
	
	public TurnInstruction(Rotation rotation)
	{
		this.rotation = rotation;
	}
	
	/**
	 * Parses the String returning a TurnInstruction instance or throwing a WrongInstructionFormatException()
	 * @param cad - text String to parse
	 * @return Instruction Reference pointing to an instance of a Instruction subclass, if it is corresponding to the String cad
	 * @throws WrongInstructionFormatException - When the String is not TURN LEFT or RIGHT or GIRAR LEFT or RIGHT
 	*/
	 
	public Instruction parse(String cad) throws WrongInstructionFormatException
	{
		String[] commands;
		commands = cad.split(" ");
		
		if (commands.length >= 2 && (commands[0].equalsIgnoreCase("TURN") || commands[0].equalsIgnoreCase("GIRAR")))
		{
			if (commands[1].equalsIgnoreCase("LEFT") )
			{
				return new TurnInstruction(Rotation.LEFT);
			}
			else if (commands[1].equalsIgnoreCase("RIGHT"))
			{	
				return new TurnInstruction(Rotation.RIGHT);
			}
			else
				throw new WrongInstructionFormatException(cad);
		}
		else
			throw new WrongInstructionFormatException(cad);
	}
	
	/**
	 * Turns the robot left or right
	 * @throws InstructionExecutionException - When the rotation is unknown
	 */
	public void execute() throws InstructionExecutionException
	{
		this.navigation.rotate(this.rotation);
		this.engine.addFuel(-Constants.LOST_FUEL);
	}
	
	/**
	 * Set the execution context. The method receives the entire engine (engine, navigation and the robot container) even though the actual implementation of execute() may not require it.
	 * @param engine - The robot engine
	 * @param navigation - The information about the game, i.e., the places, current direction and current heading to navigate
	 * @param robotContainer - The inventory of the robot
	 */
	public void configureContext(RobotEngine engine, NavigationModule navigation, ItemContainer robotContainer)
	{
		this.engine = engine;
		this.navigation = navigation;
	}

	@Override
    /**
     * Returns a description of the Instruction syntax. The string does not end with the line separator. It is up to the caller adding it before printing.
     * @return The Instruction's syntax.
     */
	public String getHelp() 
	{
		return "TURN | GIRAR < LEFT|RIGHT >";
	}
}
